package com.mvc.business.web;

import java.io.File;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.extremecomponents.table.limit.Limit;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;

import com.mvc.PdfUtils;
import com.mvc.ProjectUtils;
import com.mvc.base.model.Company;
import com.mvc.base.model.Supplier;
import com.mvc.base.model.UserNotice;
import com.mvc.base.service.CompanyManager;
import com.mvc.base.service.SupplierManager;
import com.mvc.business.model.Order;
import com.mvc.business.model.Purchase;
import com.mvc.business.model.PurchaseItem;
import com.mvc.business.service.PurchaseManager;
import com.mvc.config.ApplicationConfig;
import com.mvc.framework.dao.PropertyFilter;
import com.mvc.framework.model.BaseEntity;
import com.mvc.framework.service.DictionaryFacade;
import com.mvc.framework.service.PageManager;
import com.mvc.framework.util.DomainUtils;
import com.mvc.framework.util.FileUpDownUtils;
import com.mvc.framework.util.FrameworkContextUtils;
import com.mvc.framework.util.PageSearch;
import com.mvc.framework.util.PageUtils;
import com.mvc.framework.web.PageController;
import com.mvc.portal.service.CUserManager;
import com.mvc.portal.service.NotificationManager;
import com.mvc.security.model.User;
import com.mvc.security.service.UserManager;

@Controller
@RequestMapping("purchase")
public class PurchaseController extends PageController<Purchase> {

	private static final Logger	LOGGER	= Logger.getLogger(PurchaseController.class);

	@Autowired
	private PurchaseManager	    purchaseManager;

	@Autowired
	private UserManager<User>	userManager;

	@Autowired
	private SupplierManager	    supplierManager;

	@Autowired
	private NotificationManager	notificationManager;

	@Autowired
	private DictionaryFacade	dictionaryFacade;

	@Autowired
	private CUserManager	    cUserManager;

	@Autowired
	private CompanyManager	    companyManager;

	protected String handlePage(HttpServletRequest request, PageSearch page) {
		pageSetting(request);
		return super.handlePage(request, page);
	}

	protected void pageSetting(HttpServletRequest request) {
		request.setAttribute("users", userManager.getAll());
		request.setAttribute("suppliers", supplierManager.getAll());
		request.setAttribute("action", "page");
		request.setAttribute("template", ApplicationConfig.getTemplate());
	}

	protected String handleEdit(HttpServletRequest request, HttpServletResponse response, Integer id) throws Exception {
		if (null == id) {
			Purchase entity = new Purchase();
			// Invalid object id
			entity.setObjectId(-purchaseManager.createSystemId());
			request.setAttribute("entity", entity);
		}
		request.setAttribute("units", dictionaryFacade.getDictionariesByDictionaryId(1008));
		request.setAttribute("template", ApplicationConfig.getTemplate());
		return super.handleEdit(request, response, id);
	}

	protected String handleSave(HttpServletRequest request, ModelMap modelMap, Purchase purchase) throws Exception {
		if (purchase.getId() == null) {
			purchase.setUserId(FrameworkContextUtils.getCurrentUserId());
			purchase.setPurchaseDate(new Date());
			purchase.setFinanceStatus(Order.ORDER_FINANCE_STATUS_UNPAY);
		}
		getEntityManager().save(purchase);
		if (purchase.getStatus() == Purchase.STATUS_COMMIT) {
			List<User> users = cUserManager.getNoticeUsers(UserNotice.TYPE_ORDER_APPROVAL);
			if (users.size() > 0) {
				String subject = "采购单提交通知(" + purchase.getPurchaseNo() + ")";
				String content = "，您好：<br/>" + ProjectUtils.getParagraphIndent() + "编号为" + purchase.getPurchaseNo()
				        + "的采购单已提交，请您登录<a href='" + DomainUtils.getDynamicDomain() + "'>" + ApplicationConfig.getSystemName()
				        + "</a>审批。<br/>" + ProjectUtils.getCommonNoReplyMessage();
				for (User user : users) {
					try {
						notificationManager.sendMail(subject, user.getUserName() + content, new File[] {}, new String[] {},
						        ProjectUtils.getMailTo(user.getEmail()), new String[] {}, false);
					} catch (Exception e) {
						LOGGER.error("sendPurchaseApprovalMessages", e);
					}
				}
			}
		}
		return "redirect:edit/" + ((BaseEntity) purchase).getId() + getMessage("common.base.success", request) + "&action="
		        + request.getParameter("action");
	}

	@RequestMapping("my")
	public String my(HttpServletRequest request, HttpServletResponse response) throws Exception {
		Limit limit = PageUtils.getLimit(request);
		PageSearch page = preparePage(request, limit);
		page.getFilters().add(new PropertyFilter("EQI_userId", FrameworkContextUtils.getCurrentUserId() + ""));
		String result = handlePage(request, page);
		afterPage(request, page, IS_NOT_BACK);
		request.setAttribute("action", "my");
		return result;
	}

	@RequestMapping("unpay")
	public String unpay(HttpServletRequest request, HttpServletResponse response) throws Exception {
		Limit limit = PageUtils.getLimit(request);
		PageSearch page = preparePage(request, limit);
		page.getFilters().add(new PropertyFilter("EQI_financeStatus", Purchase.FINANCE_STATUS_UNPAY + ""));
		pageSetting(request);
		purchaseManager.financeFind(page);
		afterPage(request, page, IS_NOT_BACK);
		request.setAttribute("action", "unpay");
		return getFileBasePath() + "listPurchase";
	}

	@RequestMapping("paid")
	public String paid(HttpServletRequest request, HttpServletResponse response) throws Exception {
		Limit limit = PageUtils.getLimit(request);
		PageSearch page = preparePage(request, limit);
		page.getFilters().add(new PropertyFilter("EQI_financeStatus", Order.ORDER_FINANCE_STATUS_PAYED + ""));
		pageSetting(request);
		purchaseManager.financeFind(page);
		afterPage(request, page, IS_NOT_BACK);
		request.setAttribute("action", "paid");
		return getFileBasePath() + "listPurchase";
	}

	@RequestMapping("pay/{purchaseId}")
	public String pay(HttpServletRequest request, @PathVariable Integer purchaseId, ModelMap modelMap) throws Exception {
		boolean result = false;
		if (purchaseId != null) {
			try {
				Purchase purchase = purchaseManager.getByObjectId(purchaseId);
				if (purchase != null && purchase.getFinanceStatus() == Order.ORDER_FINANCE_STATUS_UNPAY) {
					purchase.setFinanceStatus(Order.ORDER_FINANCE_STATUS_PAYED);
					purchase.setPayDate(new Date());
					purchaseManager.save(purchase);
					Company company = companyManager.getByObjectId(purchase.getCompanyId());
					String subject = "采购单付款通知(" + purchase.getPurchaseNo() + ")";
					String content = "，您好：<br/>" + ProjectUtils.getParagraphIndent() + company.getName() + "的编号为"
					        + purchase.getPurchaseNo() + "的采购单已付款，请注意查收。<br/>" + ProjectUtils.getCommonNoReplyMessage();
					Supplier supplier = supplierManager.getByObjectId(purchase.getSupplierId());
					String emails = "";
					if (StringUtils.isNotBlank(supplier.getEmail())) {
						emails += supplier.getEmail();
					}
					if (StringUtils.isNotBlank(ApplicationConfig.getPurchasePayNoticeEmail())) {
						emails += ProjectUtils.EMAIL_SPLIT + ApplicationConfig.getPurchasePayNoticeEmail();
					}
					if (emails.length() > 0) {
						try {
							notificationManager.sendMail(subject, supplier.getName() + content, new File[] {}, new String[] {},
							        ProjectUtils.getMailTo(emails), new String[] {}, false);
						} catch (Exception e) {
							LOGGER.error("sendPurchasePayNoticeMessages", e);
						}
					}
				}
				result = true;
			} catch (Exception e) {
				LOGGER.error("pay:" + purchaseId, e);
			}
		}
		modelMap.put("result", result);
		return "jsonView";
	}

	@RequestMapping("finish/{purchaseId}")
	public String finish(HttpServletRequest request, @PathVariable Integer purchaseId, ModelMap modelMap) throws Exception {
		boolean result = false;
		if (purchaseId != null) {
			try {
				Purchase order = purchaseManager.getByObjectId(purchaseId);
				if (order != null && order.getStatus() != Purchase.STATUS_FINISHED) {
					order.setStatus(Purchase.STATUS_FINISHED);
					purchaseManager.save(order);
				}
				result = true;
			} catch (Exception e) {
				LOGGER.error("finish" + purchaseId, e);
			}
		}
		modelMap.put("result", result);
		return "jsonView";
	}

	@RequestMapping("audit")
	public String audit(HttpServletRequest request, HttpServletResponse response) throws Exception {
		Limit limit = PageUtils.getLimit(request);
		PageSearch page = preparePage(request, limit);
		page.getFilters().add(new PropertyFilter("EQI_status", Order.ORDER_STATUS_COMMIT + ""));
		handlePage(request, page);
		afterPage(request, page, IS_NOT_BACK);
		request.setAttribute("action", "audit");
		return getFileBasePath() + "listPurchase";
	}

	@RequestMapping("audit/{orderId}")
	public String audit(HttpServletRequest request, ModelMap modelMap, @PathVariable Integer orderId) {
		boolean result = false;
		if (orderId != null) {
			try {
				Purchase order = purchaseManager.getByObjectId(orderId);
				if (order.getStatus() == Purchase.STATUS_COMMIT) {
					order.setStatus(Purchase.STATUS_APPROVED);
					order.setAuditUserId(FrameworkContextUtils.getCurrentUserId());
					order.setAuditDate(new Date());
					purchaseManager.save(order);
					User applier = userManager.getByObjectId(order.getUserId());
					String subject = "采购单审批完成通知(" + order.getPurchaseNo() + ")";
					String content = "，您好：<br/>" + ProjectUtils.getParagraphIndent() + "编号为" + order.getPurchaseNo()
					        + "的采购单已审批，请您登录<a href='" + DomainUtils.getDynamicDomain() + "'>" + ApplicationConfig.getSystemName()
					        + "</a>查看详情。<br/>" + ProjectUtils.getCommonNoReplyMessage();
					try {
						notificationManager.sendMail(subject, applier.getUserName() + content, new File[] {}, new String[] {},
						        ProjectUtils.getMailTo(applier.getEmail()), new String[] {}, false);
					} catch (Exception e) {
						LOGGER.error("sendPurchaseApprovedMessages", e);
					}
					result = true;
				}
			} catch (Exception e) {
				LOGGER.error("audit" + orderId, e);
			}
		}
		modelMap.put("result", result);
		return "jsonView";
	}

	@RequestMapping("print/{orderId}")
	public String print(HttpServletRequest request, @PathVariable Integer orderId) {
		Map<String, Object> model = prepareOrderData(orderId, request);
		String orderContent = notificationManager.getTemplateString("purchase" + ApplicationConfig.getTemplate() + ".html", model);
		request.setAttribute("orderContent", orderContent);
		return getFileBasePath() + "printPurchase";
	}

	@RequestMapping("notify/{purchaseId}")
	public String notify(@PathVariable Integer purchaseId, String purchasers, Boolean customer, ModelMap modelMap,
	        HttpServletRequest request) {
		boolean result = false;
		try {
			String userEmails = purchasers;
			userEmails += ProjectUtils.EMAIL_SPLIT + request.getParameter("others");
			if (StringUtils.isNotBlank(userEmails) || customer) {
				Map<String, Object> model = prepareOrderData(purchaseId, request);
				String orderContent = notificationManager.getTemplateString("purchase" + ApplicationConfig.getTemplate() + ".html", model);
				Purchase order = (Purchase) model.get("entity");
				if (customer) {
					userEmails += ProjectUtils.EMAIL_SPLIT + order.getSupplier().getEmail();
				}
				String[] to = ProjectUtils.getMailTo(userEmails);
				if (to != null && to.length > 0) {
					Company company = order.getCompany();
					String header = ProjectUtils.getPdfHeader(company);
					String footer = ProjectUtils.getPdfFooter(company);
					File file = PdfUtils.htmlToPdf(orderContent, header, footer);
					String subject = "采购单(" + company.getName() + ":" + order.getPurchaseNo() + ")";
					notificationManager.sendMail(subject, ProjectUtils.getCNNoReplyMessage(), new File[] { file },
					        new String[] { order.getPurchaseNo() + ".pdf" }, to, new String[] {}, true);
				}
				result = true;
			}
		} catch (Exception e) {
			LOGGER.error("notify", e);
		}
		modelMap.addAttribute("result", result);
		return "jsonView";
	}

	@RequestMapping("download/{orderId}")
	public String download(@PathVariable Integer orderId, HttpServletRequest request, HttpServletResponse response) {
		try {
			Map<String, Object> model = prepareOrderData(orderId, request);
			String orderContent = notificationManager.getTemplateString("purchase" + ApplicationConfig.getTemplate() + ".html", model);
			Purchase order = (Purchase) model.get("entity");
			Company company = order.getCompany();
			String header = ProjectUtils.getPdfHeader(company);
			String footer = ProjectUtils.getPdfFooter(company);
			File file = PdfUtils.htmlToPdf(orderContent, header, footer);
			FileUpDownUtils.setDownloadResponseHeaders(response, order.getPurchaseNo() + ".pdf");
			FileUpDownUtils.downloadFile(file, response);
		} catch (Exception e) {
			LOGGER.error("download", e);
		}
		return null;
	}

	protected Map<String, Object> prepareOrderData(Integer purchaseId, HttpServletRequest request) {
		Purchase order = purchaseManager.getObject(purchaseId);
		for (PurchaseItem item : order.getPurchaseItems()) {
			item.setUnitName(dictionaryFacade.getDictionaryByDictionaryIdAndValue(1008, item.getUnit()).getName());
		}
		Map<String, Object> model = new HashMap<String, Object>();
		model.put("entity", order);
		model.put("orderItems", order.getPurchaseItems());
		model.put("staticDomain", ProjectUtils.getFullCssThemePath());
		model.put("groupName", ApplicationConfig.getGroupName());
		model.put("currency", dictionaryFacade.getDictionaryByDictionaryIdAndValue(1006, order.getCurrency()).getName());
		request.setAttribute("entity", order);
		request.setAttribute("staticDomain", ProjectUtils.getFullCssThemePath());
		request.setAttribute("groupName", ApplicationConfig.getGroupName());
		request.setAttribute("currency", dictionaryFacade.getDictionaryByDictionaryIdAndValue(1006, order.getCurrency()).getName());
		if (order.getUserId() != null) {
			User user = userManager.getByObjectId(order.getUserId());
			model.put("maker", user);
			request.setAttribute("maker", user);
		}
		if (order.getAuditUserId() != null) {
			User user = userManager.getByObjectId(order.getAuditUserId());
			if (user != null) {
				model.put("auditor", user);
				request.setAttribute("auditor", user);
			}
		}
		return model;
	}

	@RequestMapping("supplier")
	public String supplier(HttpServletRequest request, HttpServletResponse response) throws Exception {
		Limit limit = PageUtils.getLimit(request);
		PageSearch page = preparePage(request, limit);
		page.getFilters().add(new PropertyFilter("EQI_supplierId", String.valueOf(request.getSession().getAttribute("supplierId"))));
		handlePage(request, page);
		afterPage(request, page, IS_NOT_BACK);
		request.setAttribute("action", "supplier");
		return getFileBasePath() + "listPurchase";
	}

	@RequestMapping("selectToSchedule")
	public String selectToSchedule(HttpServletRequest request, HttpServletResponse response) throws Exception {
		Limit limit = PageUtils.getLimit(request);
		PageSearch page = preparePage(request, limit);
		page.getFilters().add(new PropertyFilter("EQI_status", Purchase.STATUS_APPROVED + ""));
		page.getFilters().add(new PropertyFilter("EQI_type", Purchase.PURCHASE_TYPE_ORDER + ""));
		handlePage(request, page);
		afterPage(request, page, IS_NOT_BACK);
		request.setAttribute("action", "selectToSchedule");
		return getFileBasePath() + "selectPurchase";
	}

	@RequestMapping("selectToBankStatement")
	public String selectToBankStatement(HttpServletRequest request, HttpServletResponse response) throws Exception {
		Limit limit = PageUtils.getLimit(request);
		PageSearch page = preparePage(request, limit);
		if (StringUtils.isNotBlank(request.getParameter("supplierId"))) {
			page.getFilters().add(new PropertyFilter("EQI_supplierId", request.getParameter("supplierId")));
		}
		page.getFilters().add(new PropertyFilter("EQI_status", Purchase.STATUS_FINISHED + ""));
		// handlePage(request, page);
		pageSetting(request);
		purchaseManager.findForBankStatementImport(page);
		afterPage(request, page, IS_NOT_BACK);
		request.setAttribute("action", "selectToBankStatement");
		return getFileBasePath() + "selectBankStatementPurchase";
	}

	@RequestMapping("backward/{orderId}")
	public String backward(HttpServletRequest request, ModelMap modelMap, @PathVariable Integer orderId) {
		boolean result = false;
		if (orderId != null) {
			try {
				Purchase order = purchaseManager.getByObjectId(orderId);
				if (order.getFinanceStatus() != Order.ORDER_FINANCE_STATUS_PAYED
				        && (order.getStatus() == Order.ORDER_STATUS_APPROVED || order.getStatus() == Order.ORDER_STATUS_COMMIT)) {
					String reason = request.getParameter("reason");
					order.setStatus(Order.ORDER_STATUS_BACKWARD);
					order.setAuditUserId(null);
					order.setAuditDate(null);
					order.setBackwardReason(reason);
					purchaseManager.save(order);
					User applier = userManager.getByObjectId(order.getUserId());
					String subject = "采购单审批退回通知(" + order.getPurchaseNo() + ")";
					String content = "，您好：<br/>" + ProjectUtils.getParagraphIndent() + "编号为" + order.getPurchaseNo() + "的采购单已退回，原因为："
					        + reason + "。请您登录<a href='" + DomainUtils.getDynamicDomain() + "'>" + ApplicationConfig.getSystemName()
					        + "</a>查看详情。<br/>" + ProjectUtils.getCommonNoReplyMessage();
					try {
						notificationManager.sendMail(subject, applier.getUserName() + content, new File[] {}, new String[] {},
						        ProjectUtils.getMailTo(applier.getEmail()), new String[] {}, false);
					} catch (Exception e) {
						LOGGER.error("sendPurchaseBackwardMessages", e);
					}
					result = true;
				} else {
					modelMap.addAttribute("message", "已经付款了，不能再修改。");
				}
			} catch (Exception e) {
				LOGGER.error("backward" + orderId, e);
			}
		}
		modelMap.put("result", result);
		return "jsonView";
	}

	@Override
	public PageManager<Purchase> getEntityManager() {
		return purchaseManager;
	}

	@Override
	public String getFileBasePath() {
		return "business/";
	}

}
